import { defineComponent, ref, inject, computed, watchEffect, withModifiers } from 'vue'
import { NButton } from 'naive-ui'
import pageStyle from '../styles/index.module.scss'
import YnForm from '@/components/yFormData/QuestionTypes/YnForm'
import YnFormItem from '@/components/yFormData/QuestionTypes/YnFormItem'
import Draggable from 'vuedraggable'
import { getQuestionsInfo } from '@/utils/dyForm'
import DynamicComponent from '@/components/yFormData/QuestionTypes/index'
import type { questionSideListState, basicState, RowState } from '@/types/baseConfig'
import type { PropType, Ref } from 'vue'

const ToolBtn = defineComponent({
  props: {
    element: {
      type: Object as PropType<questionSideListState>
    }
  },
  emits: ['del'],
  setup(props: any, { emit }) {
    const currenUid = inject('currenUid') as Ref<string>
    return () => (
      <div class="btns">
        {currenUid.value === props.element.uid && (
          <>
            <div class="del">
              <i class="esayIcon esayIcon-icon-"></i>
            </div>
            <div
              class="del"
              onClick={withModifiers(() => {
                emit('del')
              }, ['stop'])}
            >
              <i class="esayIcon esayIcon-shanchu"></i>
            </div>
          </>
        )}
        {props.element.commonForm.showParams.length > 0 && (
          <div class="del">
            <i class="esayIcon esayIcon-yincang"></i>
          </div>
        )}
      </div>
    )
  }
})

const RowChilder = defineComponent({
  props: {
    modelValue: {
      type: Array as PropType<questionSideListState[]>,
      default: () => []
    },
    isRow: Boolean,
    row: {
      type: Object as PropType<RowState>,
      default: () => {
        return {}
      }
    }
  },
  emits: ['update:modelValue', 'currenChange', 'delEmpty'],
  setup(props: any, { emit }) {
    const $clone = inject('$clone') as <T>(data: T) => T
    const questions = ref<questionSideListState[]>([])
    watchEffect(() => {
      questions.value = props.modelValue
    })
    const draStyle = computed(() => {
      let style: any = {}
      if (props.isRow) {
        style.gridGap = `${props.row.yGap}px ${props.row.xGap}px`
        const arr = $clone(questions.value).map((el: any) => {
          return el.ColLayoutForm.width
        })
        style.gridTemplateColumns = arr.join(' ')
        const names = ['autoFlow', 'alignItems', 'justifyItems', 'alignContent', 'justifyContent']
        names.forEach((el: string) => {
          if (props.row[el]) {
            style[el] = props.row[el]
          }
        })
        if (props.row?.zdyStyle) {
          style = {
            ...style,
            ...props.row.zdyStyle
          }
        }
      }
      return style
    })
    const addChange = (evt: any) => {
      const newIndex = evt.newIndex
      const info = $clone(questions.value[newIndex])
      questions.value[newIndex] = getQuestionsInfo(info)
      emit('update:modelValue', questions.value)
      currenChange(questions.value[newIndex], newIndex)
    }
    const sortChange = (evt: any) => {
      const newIndex = evt.newIndex
      emit('update:modelValue', questions.value)
      currenChange(questions.value[newIndex], newIndex)
    }
    const currenUid = inject('currenUid') as Ref<string>
    const setCurenUid = inject('setCurenUid') as (e: string) => void
    const setCurren = inject('setCurren') as (e: number[]) => void
    const currenChange = (e: questionSideListState, index: number) => {
      setCurenUid(e.uid)
      if (!props.isRow) {
        setCurren([index])
      } else {
        emit('currenChange', [index])
      }
    }
    const handDel = (index: number) => {
      questions.value.splice(index, 1)
      if (questions.value.length === 0) {
        if (props.isRow) {
          emit('delEmpty')
        } else {
          setCurren([])
          setCurenUid('')
        }
      } else if (index === questions.value.length) {
        const info: questionSideListState | undefined = questions.value.at(-1)
        if (info) {
          currenChange(info, questions.value.length - 1)
        }
      } else if (questions.value.length - 1 >= index) {
        currenChange(questions.value[index], index)
      }
      emit('update:modelValue', questions.value)
    }

    const backChange = (arr: number[], index: number) => {
      if (props.isRow) {
        emit('currenChange', [index, ...arr])
      } else {
        setCurren([index, ...arr])
      }
    }
    return () => (
      <>
        <Draggable
          v-model={questions.value}
          group={{ name: 'question', pull: 'clone' }}
          ghostClass="ghost"
          animation="300"
          item-key="uid"
          style={{ draStyle }}
          class={props.isRow && 'row'}
          onAdd={addChange}
          onSort={sortChange}
        >
          {{
            item: ({ element, index }: { element: questionSideListState; index: number }) =>
              element.type === 'RowLayout' ? (
                <div
                  class={`zdy-row ${currenUid.value === element.uid && 'card-active'}`}
                  style={{ paddingTop: element.commonForm.showParams.length > 0 ? '25px' : '0' }}
                  onClick={withModifiers(() => {
                    currenChange(element, index)
                  }, ['stop'])}
                >
                  <ToolBtn element={element} onDel={() => handDel(index)} />
                  {element.RowLayoutForm?.childer && (
                    <RowChilder
                      isRow
                      row={element.RowLayoutForm}
                      v-model={element.RowLayoutForm.childer}
                      onCurrenChange={(arr: number[]) => backChange(arr, index)}
                      onDelEmpty={() => currenChange(element, index)}
                    />
                  )}
                </div>
              ) : (
                <div
                  class={`card ${currenUid.value === element.uid && 'card-active'} ${
                    props.isRow && 'card-grid'
                  }`}
                  onClick={withModifiers(() => {
                    currenChange(element, index)
                  }, ['stop'])}
                >
                  <ToolBtn element={element} onDel={() => handDel(index)} />
                  <YnFormItem
                    {...element.formItem}
                    label={element.commonForm.labelName}
                    path={element.commonForm.labelKey}
                  >
                    <DynamicComponent
                      component={element.type}
                      comp-data={element}
                    ></DynamicComponent>
                  </YnFormItem>
                </div>
              )
          }}
        </Draggable>
      </>
    )
  }
})

export default defineComponent({
  props: {
    compData: {
      type: Object as PropType<basicState>,
      default: () => {
        return {}
      }
    }
  },
  emits: ['remove', 'prive', 'importJson', 'exportJson', 'exportCode', 'sfc'],
  setup(props: any, { emit }: any) {
    const curren = inject('curren') as Ref<number[]>
    const questions = inject('questions') as Ref<questionSideListState[]>
    const currenName = computed(() => {
      if (curren.value.length > 0) {
        return curren.value[0] + 1
      }
      return 0
    })
    return () => (
      <>
        <div class={pageStyle.movingMain}>
          <div class="movingMain-top flex items-center justify-between">
            <div class="tools"></div>
            <div class="btns">
              <NButton class="press-down" text type="primary" onClick={() => emit('remove')}>
                <i class="esayIcon esayIcon-shanchu"></i>
                <span class="ml-[3px]">清空</span>
              </NButton>
              <NButton
                class="press-down"
                style={{ marginLeft: '15px' }}
                text
                type="primary"
                onClick={() => emit('prive')}
              >
                <i class="esayIcon esayIcon-yulan"></i>
                <span class="ml-[3px]">预览</span>
              </NButton>
              <NButton
                class="press-down"
                style={{ marginLeft: '15px' }}
                text
                type="primary"
                onClick={() => emit('importJson')}
              >
                <span class="ml-[3px]">导入JSON</span>
              </NButton>
              <NButton
                class="press-down"
                style={{ marginLeft: '15px' }}
                text
                type="primary"
                onClick={() => emit('exportJson')}
              >
                <span class="ml-[3px]">导出JSON</span>
              </NButton>
              <NButton
                class="press-down"
                style={{ marginLeft: '15px' }}
                text
                type="primary"
                onClick={() => emit('exportCode')}
              >
                <span class="ml-[3px]">导出代码</span>
              </NButton>
              <NButton
                class="press-down"
                style={{ marginLeft: '15px' }}
                text
                type="primary"
                onClick={() => emit('sfc')}
              >
                <span class="ml-[3px]">生成SFC</span>
              </NButton>
            </div>
          </div>
          <div class="movingMain-con">
            <div class={pageStyle.movingMainScroll}>
              <div class={pageStyle.movingMainScrollContent}>
                <header>
                  <span>表单设计</span>
                  <span>
                    {currenName.value}/{questions.value.length}
                  </span>
                </header>
                <YnForm {...props.compData}>
                  <RowChilder v-model={questions.value} />
                </YnForm>
              </div>
            </div>
          </div>
        </div>
      </>
    )
  }
})
